﻿/*
 *  WMI_PHP_LOCK - 2015 (c) Nguyen Hoang Tung
 * http://tungpc.com - admin@tungpc.com
 * 
 * This class obfuscator php source code. 
 * Use DES 128 ECB encrypt hard.
 * Use Base64 encrypt basic
 * This core encrypt with DES ECB 128 very strong!
 
 
 
 USE:
            WMI_PHP_LOCK php = new WMI_PHP_LOCK();
            php._isExpri = true;
            php._isIP = true;
            php._isCopy = true;

            php.__Copy = "Code protect by Tungpc.com";
            php._ExpDate = new DateTime(2015, 4, 30);
            php._IP_Add = "127.0.0.1";
            php.__Prefix_Len = 32;
            return php.PHP_LOCK(<input php code>);
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Xml;
using System.Net;
using System.Security.Cryptography;

namespace WMI_PHP_OBFS
{
    public class WMI_PHP_LOCK
    {
        public bool _isExpri { get; set; }
        public bool _isIP { get; set; }
        public bool _isDomain { get; set; }
        public bool _isCopy { get; set; }

        public DateTime _ExpDate { get; set; }
        public string _Domain { get; set; }
        public string _IP_Add { get; set; }
        public int __Prefix_Len { get; set; }
        public string __Copy { get; set; }

        private string __Start { get; set; }
        private Dictionary<string, string> alias_ref{get;set;}
        private string refx { get; set; }
        WMI_Crypt Crypt = new WMI_Crypt();

        public void PHP_AUTO(string pof) {
            string enc =  PHP_LOCK(ReadFileString(pof));
            this.write_text(pof, enc);
            string lenvar = ToHex( (new System.IO.FileInfo(pof).Length));
            string enc2 = ReadFileString(pof).Replace("__LEN__", lenvar).Replace("__FNAME__", Path.GetFileName(pof));
            this.write_text(pof,enc2);

        }

        public string PHP_LOCK(string php) 
        {
            try
            {
                __Prefix_Len = (__Prefix_Len < 2) ? 32 : __Prefix_Len;
                __Start = RandomString(__Prefix_Len);

                string ream = "";
                if (_isIP)
                {
                    ream += php_lock_ip();
                }
                if (_isDomain)
                {
                    ream += php_lock_domain();
                }
                if (_isExpri)
                {
                    ream += php_lock_time();
                }
                ream += php_lock_basic(php);

                //return "<?php "+ream;
                

                //return Crypt.Base64Encode("?><?php eval(" + php_lock_basic(ream) +";);" );
                //return Crypt.Base64Encode("<?php eval(" + php_lock_basic(ream) + ");");
                string phpav = Crypt.Base64Encode("?>" + PHP_PACKET(PHP_Mask(ream)));
                return  PHP_PACKET( php_reduct(phpav,phpav.Length));
                //return Crypt.Base64Encode("?>" + PHP_PACKET(PHP_Mask(ream)));
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        
        private string PHP_Mask(string Ream) {
            //old
            string mask = " eval(base64_decode(\"" + Crypt.Base64Encode(Ream) + "\")); ";
            return " eval(base64_decode(\"" + Crypt.Base64Encode(php_lock_basic("<?php eval(base64_decode(\"" + Crypt.Base64Encode(mask) + "\"));")) + "\"));";


            //string mask = " eval(base64_decode(\""+Crypt.Base64Encode(Ream)+"\")); ";
            //return mask;
            //return " eval(base64_decode(\"" + Crypt.Base64Encode(php_lock_basic("eval(base64_decode(\"" + Crypt.Base64Encode(mask) + "\"));")) + "\"));";
        }

        private string PHP_PACKET(string php) {
            string cpr = (_isCopy == true) ? "/*  Protected by phpCipher.Net - " + __Copy + " - This file is protected by copyright law and provided under license. Reverse engineering of this file is strictly prohibited.  */" : "/*   Protected by phpCipher.Net - This file is protected by copyright law and provided under license. Reverse engineering of this file is strictly prohibited.     */";
            return "<?php " + cpr +php;

            //return "<?php " + cpr + php_reduct(php,php.Length+50);
        }

        private string php_lock_time() {
            string _exp = time(_ExpDate).ToString();
            return php_lock_basic("<?php (time() > " + _exp + ") ? exit(\"Core expired! please contact administrator now!\") : ''; ?>");
        }

        private string php_lock_domain() {
            return php_lock_basic("<?php ($_SERVER['SERVER_NAME'] != '" + _Domain + "') ? exit(\"Invalid Domain name!\") : ''; ?>");
        }

        private string php_lock_ip() {
            return php_lock_basic("<?php (gethostbyname($_SERVER['HTTP_HOST'])!='"+_IP_Add+"') ? exit('Invalid Host') : '';?>");
        }

        private string php_lock_basic(string php) {
            WMI_Crypt Crypt = new WMI_Crypt();
            string key = RandomString(32); ;
            string IV = RandomString(16);

            string td_var = RandomString(__Prefix_Len);
            string dec_var = RandomString(__Prefix_Len);

            //string template = " $" + td_var + " = mcrypt_module_open(base64_decode(\"" + Crypt.Base64Encode("rijndael-128") + "\"), '', base64_decode(\"" + Crypt.Base64Encode("ecb") + "\"), ''); mcrypt_generic_init($" + td_var + ", \"__KEY__\", \"__IV__\"); $" + dec_var + " = mdecrypt_generic($" + td_var + ", base64_decode(\"__ENC__\")); mcrypt_generic_deinit($" + td_var + ");mcrypt_module_close($" + td_var + "); eval( trim($" + dec_var + ")); ";
            string template = " $" + td_var + " = mcrypt_module_open(base64_decode(\"" + Crypt.Base64Encode("rijndael-128") + "\"), '', base64_decode(\"" + Crypt.Base64Encode("ecb") + "\"), ''); mcrypt_generic_init($" + td_var + ", \"__KEY__\", \"__IV__\"); eval(trim( mdecrypt_generic($" + td_var + ", base64_decode(\"__ENC__\")))); mcrypt_generic_deinit($" + td_var + ");mcrypt_module_close($" + td_var + ");  ";
            string[] _define = "mcrypt_module_open,mcrypt_generic_init,mdecrypt_generic,base64_decode,mcrypt_generic_deinit,mcrypt_module_close,trim".Split(',');
            this.mix_fx(_define);
            
            //string pencode = refx+" "+ template.Replace("__KEY__", key).Replace("__IV__", IV).Replace("__ENC__", Crypt.ECB_Encrypt("?>"+php, key, IV));
            string pencode = refx + " " + template.Replace("__KEY__", key).Replace("__IV__", IV).Replace("__ENC__", Crypt.ECB_Encrypt("?>" + php, key, IV));

            foreach(string c in _define){
                pencode = pencode.Replace(c,alias_ref[c]);
            }

            return pencode;
        }

        private string php_reduct(string php,int len) {
            WMI_Crypt Crypt = new WMI_Crypt();

            string[] define = "fopen,fread,fclose,base64_decode,base64_encode,preg_replace,str_replace".Split(',');
            string handler_var = RandomString(__Prefix_Len);
            string contents_var = RandomString(__Prefix_Len);
            string lenght_var = RandomString(__Prefix_Len);
            string repc_var = RandomString(__Prefix_Len*2);
            string f_var = RandomString(__Prefix_Len);

            //string template = "$" + lenght_var + "=__LEN__; $" + handler_var + " = fopen( __FILE__ , \"rb\"); $" + contents_var + " = fread($" + handler_var + ", $" + lenght_var + "); fclose($" + handler_var + ");eval( base64_decode(str_replace(base64_decode(\"" + Crypt.Base64Encode( repc_var) + "\"),\"\", str_replace(\"?>\",\"\", strstr(preg_replace(\"#(<\\?php).*?(return;\\?>)#\", \"$1$2\", preg_replace(\"/\\s+/\", \"\", $" + contents_var + ")),\"?>\")) )));";
            string template = "$" + f_var + "= __FILE__;$" + lenght_var + "=__LEN__;$" + handler_var + " = fopen( $" + f_var + " , base64_decode(\"" + Crypt.Base64Encode("rb") + "\"));$" + contents_var + " = fread($" + handler_var + ", $" + lenght_var + "); fclose($" + handler_var + ");eval( base64_decode(str_replace(base64_decode(\"" + Crypt.Base64Encode(repc_var) + "\"),\"\", str_replace(\"?>\",\"\", strstr(preg_replace(base64_decode(\"" + Crypt.Base64Encode("#(<\\?php).*?(return;\\?>)#") + "\"), base64_decode(\"" + Crypt.Base64Encode("$1$2") + "\"), preg_replace(\"/\\s+/\", \"\", $" + contents_var + ")),\"?>\")) )));";
            //string template = "$" + f_var + "= __FILE__;$" + lenght_var + "=__LEN__; $" + handler_var + " = fopen( $" + f_var + " , base64_decode(\"" + Crypt.Base64Encode("rb") + "\"));eval(\"if( basename(str_replace(\"\\\",\"/\", $" + f_var + ")) != '__FNAME__'){ exit('Base code is invalid!'); }\"); $" + contents_var + " = fread($" + handler_var + ", $" + lenght_var + "); fclose($" + handler_var + ");eval( base64_decode(str_replace(base64_decode(\"" + Crypt.Base64Encode(repc_var) + "\"),\"\", str_replace(\"?>\",\"\", strstr(preg_replace(base64_decode(\"" + Crypt.Base64Encode("#(<\\?php).*?(return;\\?>)#") + "\"), base64_decode(\"" + Crypt.Base64Encode("$1$2") + "\"), preg_replace(\"/\\s+/\", \"\", $" + contents_var + ")),\"?>\")) )));";

            mix_fx(define);

            string pencode = refx + " " + template;
            foreach (string c in define)
            {
                pencode = pencode.Replace(c, alias_ref[c]);
            }
            int flength = pencode.Length;
            flength = pencode.Length + flength.ToString().Length+len;
            //pencode = pencode.Replace("__LEN__", ToHex(flength+207));
            return pencode+" return; ?>"+php.Insert(new Random().Next(1,php.Length),repc_var);
            
        }

        private string php_reduct_p2(string pof) {
            string enc = ReadFileString(pof);
            Regex ex= new Regex("<\\?php (.*?) return");
            Match mc = ex.Match(enc);
            string[] define = "base64_decode".Split(',');
            string templ = "eval(base64_decode(\"__ENC__\"));";
            mix_fx(define);

            if(mc.Success){
                templ = templ.Replace("__ENC__",Crypt.Base64Encode(enc));
                foreach (string c in define)
                {
                    templ = templ.Replace(c, alias_ref[c]);
                }
                return templ;
            }
            return enc;


        }

        private string ToHex(long len)
        {
            return String.Format("0x{0:X}", len);
        }

        private string Proxy_call(string php)
        {
            WMI_Crypt Crypt = new WMI_Crypt();
            string key = RandomString(32); ;
            string IV = RandomString(16);

            string td_var = RandomString(__Prefix_Len);
            string dec_var = RandomString(__Prefix_Len);
            string avc_var = RandomString(__Prefix_Len);
            string str_var = RandomString(__Prefix_Len);
            string deep_var = RandomString(__Prefix_Len);
            
            string template = " $" + td_var + " = mcrypt_module_open(base64_decode(\"" + Crypt.Base64Encode("rijndael-128") + "\"), '', base64_decode(\"" + Crypt.Base64Encode("ecb") + "\"), ''); mcrypt_generic_init($" + td_var + ", \"__KEY__\", \"__IV__\"); $" + dec_var + " = mdecrypt_generic($" + td_var + ", base64_decode(\"__ENC__\")); mcrypt_generic_deinit($" + td_var + ");mcrypt_module_close($" + td_var + ");$" + deep_var + "=base64_decode('" + Crypt.Base64Encode(__Start) + "'); call_user_func( $" + deep_var + " , trim($" + dec_var + ")); ";
            string[] _define = "htmlspecialchars_decode,mcrypt_module_open,mcrypt_generic_init,mdecrypt_generic,base64_decode,mcrypt_generic_deinit,mcrypt_module_close,trim,call_user_func".Split(',');
            this.mix_fx(_define);

            string pencode = refx + " " + template.Replace("__KEY__", key).Replace("__IV__", IV).Replace("__ENC__", Crypt.ECB_Encrypt("?>" + php, key, IV));

            foreach (string c in _define)
            {
                pencode = pencode.Replace(c, alias_ref[c]);
            }
            return pencode;


        }

        private void mix_fx(string[] _fx)
        {
            StringBuilder sb = new StringBuilder();

            string fullfx = string.Join(string.Empty, _fx);
            string check = mixerstring(fullfx);

            char[] avc = check.ToCharArray();
            string varible = RandomString(__Prefix_Len);

            string urlcode = "$" + varible + "=urldecode('" + strtohex(check) + "'); ";

            alias_ref = new Dictionary<string, string>();

            for (int v = 0; v < _fx.Length;v++ )
            {
                List<string> varc = new List<string>();
                string param = RandomString(__Prefix_Len);
                //string inc = "base64_decode";
                for (int i = 0; i < _fx[v].Length; i++)
                {
                    //sb.Append(Convert.ToString(Array.LastIndexOf(avc, _fx.ToCharArray()[i])) + " [" + _fx.ToCharArray()[i] + "] ");
                    //sb.Append( Convert.ToString(Array.LastIndexOf(avc, _fx.ToCharArray()[i])) );
                    varc.Add("$" + varible + "{" + Convert.ToString(Array.LastIndexOf(avc, _fx[v].ToCharArray()[i])) + "}");
                }

                string querys = "";
                string[] varcv = varc.ToArray();
                foreach (string c in varcv)
                {
                    querys += "." + c;
                }
                string function = "$GLOBALS['" + param + "']=" + querys.Remove(0, 1) + ";";
                alias_ref[_fx[v]] = "$GLOBALS['" + param + "']";
                sb.Append(function);
            }
            refx = urlcode + sb.ToString();
        }

        private string strtohex(string str) {
            byte[] ba = Encoding.Default.GetBytes(str);
            var hexString = BitConverter.ToString(ba);
            hexString = hexString.Replace("-", "%");
            return "%" + hexString;
        }

        private string mixerstring(string _input)
        {
            string a1 = _input + RandomString(__Prefix_Len+20);
            char[] av = a1.ToCharArray();
            Shuffle(av);
            StringBuilder sb = new StringBuilder();
            foreach (char c in av)
            {
                sb.Append(c);
            }
            return sb.ToString();
        }

        private static void Shuffle<T>(T[] array)
        {
            int n = array.Length;
            for (int i = 0; i < n; i++)
            {
                int r = i + (int)(new Random().NextDouble() * (n - i));
                T t = array[r];
                array[r] = array[i];
                array[i] = t;
            }
        }

        public string RandomString(int size)
        {
            return RandomUtil.GetRandomAlphanumericString(size);
        }

        private long time(DateTime time)
        {
            DateTime unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0);
            TimeSpan span = time.Subtract(unixEpoch);

            return (long)span.TotalSeconds;
        }

        public string ReverseString(string s)
        {
            char[] arr = s.ToCharArray();
            Array.Reverse(arr);
            return new string(arr);
        }

        public void write_text(string pof,string lines){
            StreamWriter writetext = new StreamWriter(pof);
            writetext.WriteLine(lines);
            writetext.Close();
        }

        public string read_text(string pof) {
            StreamReader readtext = new StreamReader(pof);
            string readmetext = readtext.ReadLine();
            readtext.Close();
            return readmetext;
        }

        public string ReadFileString(string path)
        {
            // Use StreamReader to consume the entire text file.
            using (StreamReader reader = new StreamReader(path))
            {
                return reader.ReadToEnd();
            }
        }

    }

    static class RandomUtil
    {
        /// <summary>
        /// Get random string of 11 characters.
        /// </summary>
        /// <returns>Random string.</returns>
        public static string GetRandomString()
        {
            string path = Path.GetRandomFileName();
            path = path.Replace(".", ""); // Remove period.
            return path;
        }

        public static string GetRandomAlphanumericString(int length)
        {
            const string alphanumericCharacters =
                "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
                "abcdefghijklmnopqrstuvwxyz";
            return GetRandomString(length, alphanumericCharacters);
        }

        public static string GetRandomString(int length, IEnumerable<char> characterSet)
        {
            if (length < 0)
                throw new ArgumentException("length must not be negative", "length");
            if (length > int.MaxValue / 8) // 250 million chars ought to be enough for anybody
                throw new ArgumentException("length is too big", "length");
            if (characterSet == null)
                throw new ArgumentNullException("characterSet");
            var characterArray = characterSet.Distinct().ToArray();
            if (characterArray.Length == 0)
                throw new ArgumentException("characterSet must not be empty", "characterSet");

            var bytes = new byte[length * 8];
            new RNGCryptoServiceProvider().GetBytes(bytes);
            var result = new char[length];
            for (int i = 0; i < length; i++)
            {
                ulong value = BitConverter.ToUInt64(bytes, i * 8);
                result[i] = characterArray[value % (uint)characterArray.Length];
            }
            return new string(result);
        }

    }


}
